package com.tedu.api.list;

import org.junit.Test;

import java.awt.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 迭代器：打印集合的元素【接口】
 * 集合提供自己一套输出集合元素的方法---迭代器【普通for，增强for】
 * 包位置：java.util
 * Iterator    接口
 * 该接口是集合的接口，提供遍历元素的相关操作：问、取、删
 *
 * iterator()方法    返回值Iterator--- Collection接口类已经存在方法
 * 作用：获取一个用于遍历当前集合迭代器的实现类实例
 *
 * 遍历规则：问、取、删（删不是必须操作）
 */
public class Collection_iterator {
    @Test
    public void testIterator(){
        //创建集合
        Collection c1=new ArrayList();
        c1.add("one");c1.add("two");c1.add("three");
        c1.add("four");c1.add("five");c1.add("six");
    //iterator()获取一个用于遍历当前集合迭代器的实现类实例
        Iterator it=c1.iterator();
    //拿到集合所有元素，封装迭代器创建对象过程--理解迭代器实例
        //获取Iterator--获取集合的某个元素，规则：问、取、删
      //Iterator接口---hasNext()，获取集合元素
        //集合：如果说：70个元素  ---循环  while
        while(it.hasNext()){//①问：集合有没有元素
            //迭代器集合：获取元素    |   next()获取元素
            String str=(String)it.next();  //②取：获取集合元素
            System.out.println("迭代器"+str);
        }
        //迭代器是否改变集合元素内容
        System.out.println(c1);
    }

    /**
     * 普通for--遍历c1集合    集合：size()
     * 语法：for(int i=0;i<c1.size();i++){}
     * 增强for--遍历c1集合    接收类型：Object
     * 语法：for(Object c:c1){}
     * Iterator迭代器--集合提供接口
     */
    @Test
    public void testCollection(){
        //创建集合
        Collection c1=new ArrayList();
        c1.add("one");c1.add("two");c1.add("three");
        c1.add("four");c1.add("five");c1.add("six");
        for(int  i = 0;i < c1.size();i++){
            System.out.println("普通for："+c1.toArray()[i]);  //打印
        }
        for (Object c:c1){
            System.out.println("增强for："+c);
        }
    }
    /**
     * remove()  删除    Iterator迭代器    增强for
     * 作用：删除相同的元素数据 提醒：针对Next方法【测】
     */
    @Test
    public void testRemove(){
        Collection c=new ArrayList();
        c.add("西游记");c.add("水浒传");
        //需求：通过迭代器删掉 #
        Iterator it=c.iterator();
        while(it.hasNext()){//问：有没有元素
            String str=(String) it.next();    //取：有元素--打印元素
      //       c.remove("#");//Collection中存在remove()
            //删除一定是迭代器
            if("#".equals(str)) {//如果#是我们拿到的str元素中的#
                it.remove();      //那么，删除元素
            }
        }
        System.out.println("迭代器删除："+c);
    }
    /**
     * 增强for----底层使用Iterator迭代器【问、取和删】
     * c.remove("#")是Collection的删除方法，并不是迭代器方法
     * 需求：删除集合中元素“#”
     */
    @Test
    public void testFor(){
        Collection c=new ArrayList();
        c.add("西游记");c.add("#");c.add("水浒传");
        for (Object  o:c){  //类型  类型引用：  集合引用
            String str=(String)o;  //强转：拿到一个字符串类型
        //    if("#".equals(str)){
                c.remove("#");
        //    }
        }
        System.out.println("删除集合元素："+c);
    }
    /**
     *   E    element  泛型    JDK1.5新特性
     *   结合集合出现，约束集合的使用类型[基本数据类型，引用类型，包装类]
     *   泛型的原型：Object，泛型是编译器认可的，JVM虚拟机并不认可
     *   使用泛型编译器，把泛型当成Object类型执行，便于编译器检查
     *   类型以及自动造型操作
     *
     *   JDK1.5泛型使用：
     *   Collection类型：<基本类型，引用类型，包装类> c
     *   =new ArrayList类型：基本类型，引用类型，包装类();
     *
     *   JDK1.7泛型使用
     *   Collection类型，<基本类型，引用类型，包装类> c
     *   =new ArrayList<>();
     *
     *   泛型：自动推导      通配符：？  表示任意类型
     *   Collection类型，<类型：?> c
     *   =new ArrayList<>();
     *
     *   Collection类型，<类型：?  extends/super  父类/接口/类> c
     *   =new ArrayList<>();
     *   优点：保证类型安全  提高代码重用性和灵活性
     *   限定集合传入类型
     */
    @Test
    public void testType(){
        //针对于泛型的自动推导通配符？的一个测试
        Collection<?> c1=new ArrayList<>();
        c1.add(null);    //结论：并不是匹配所有类型，只能传空



        Collection<String> c=new ArrayList<String>();
        c.add("123");c.add("456");c.add("789");
        //遍历Iterator
        Iterator<String> it=c.iterator();
        while (it.hasNext()){
            String str=it.next();
            System.out.println(str);
        }
    }
}





//-----限定集合传入类型
class  Fruit{
    private String name;//成员变量

    public Fruit(String name) {  //有参构造器
        this.name = name;
    }

    public String getName() {  //方法
        return name;
    }
}
class  Apple extends Fruit{
    public Apple() {
        super("苹果");  //调用父类有参数构造器，传入name名称
    }
}
class  Orange extends Fruit{
    public Orange() {
        super("橘子");  //调用父类有参数构造器，传入name名称
    }
}
//测试类--泛型上界
class TestJob{
    //泛型上界  1.定义静态方法：制定泛型规则--集合中类型约定为Apple与Orange
    private static void printFruit(Collection<? extends Fruit>fruits){
        //2.增强for循环打印：集合中类型约定为Apple与Orange
        for(Fruit fruit:fruits){
            //3.方法能进入：Apple或Orange----打印名字
            System.out.println(fruit.getName());
        }
    }

    public static void main(String[] args) {
        Collection<Apple> apples=new ArrayList<>();
        apples.add(new Apple());     //集合对象添加：Apple对象
        Collection<Orange> oranges=new ArrayList<>();
        oranges.add(new Orange());    //集合对象添加：Orange对象
        printFruit(apples);  //测试：打印出：苹果
        printFruit(oranges);
        //假设：西瓜
//        Collection<String> strings=new ArrayList<>();
//        strings.add(new String());
//        printFruit(strings);
    }
}